package com.glsc.ngateway.platform.service.easyflow;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.glsc.ngateway.common.api.common.enums.DictConstant;
import com.glsc.ngateway.common.api.common.enums.PlatformConstant;
import com.glsc.ngateway.common.api.flowable.dto.FlowDoTaskRespDto;
import com.glsc.ngateway.common.api.flowable.dto.FlowStartupFormDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamCreateDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamDeleteDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamDoTaskDto;
import com.glsc.ngateway.common.api.flowable.dto.param.ParamRollbackDto;
import com.glsc.ngateway.common.api.flowable.dto.task.config.ProcessEditConfigDto;
import com.glsc.ngateway.common.api.flowable.resp.FlowableResponse;
import com.glsc.ngateway.common.api.flowable.resp.ResponseCreateDto;
import com.glsc.ngateway.common.api.flowable.resp.ResponseMsgDto;
import com.glsc.ngateway.common.api.flowable.resp.ResponseSituationDto;
import com.glsc.ngateway.common.api.platform.dto.user.PlatformUserDto;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.easyflow.BaseFlowForm;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.platform.service.FlowCommonService;
import com.glsc.ngateway.platform.service.UserService;
import com.glsc.ngateway.platform.service.easyflow.dto.FlowDataDto;
import com.glsc.ngateway.platform.service.easyflow.dto.ParamDoTaskRespDto;
import com.glsc.ngateway.platform.service.easyflow.dto.WorkflowMsgDto;
import com.glsc.ngateway.platform.service.easyflow.enums.FlowConstant;
import com.glsc.ngateway.platform.service.itflow.config.ProcessEditConfigService;
import com.glsc.ngateway.platform.utils.JsonTool;
import com.glsc.ngateway.platform.utils.RequestTool;
import com.glsc.ngateway.platform.utils.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.Assert;

import javax.annotation.Resource;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zzp
 * @date 2024/03/05
 * 流程策略模板类
 */
@Slf4j
public abstract class AbstractEasyFlowStrategy<TYPEFORM extends BaseFlowForm> {
    @Resource
    @Qualifier("transactionManagerMysql")
    private PlatformTransactionManager transactionManager;

    @Resource
    private FlowCommonService flowableService;

    @Resource
    private ProcessEditConfigService processEditConfigService;

    @Resource
    private EasyFlowMessageSender easyFlowMessageSender;

    @Resource
    private UserService userService;

    @Resource
    private RequestTool requestTool;

    /**
     * 各种流程类型任务节点处理实例聚合
     */
    private Map<String, AbstractEasyFlowTaskHandle> flowTaskHandleMap;

    @Autowired
    public void setFlowTaskHandleMap(List<AbstractEasyFlowTaskHandle> flowTaskHandleList) {
        this.flowTaskHandleMap = flowTaskHandleList.stream().collect(Collectors.toMap(item -> item.getProcessDefineKey(), strategy -> strategy));
    }

    /**
     * 流程类型Id
     */
    public abstract String getProcessDefineKey();

    /**
     * 获取流程任务创建附加处理
     */
    public AbstractEasyFlowTaskHandle getFlowTaskHandle() {
        if (CollectionUtil.isNotEmpty(flowTaskHandleMap)
                && Objects.nonNull(flowTaskHandleMap.get(this.getProcessDefineKey()))) {
            return flowTaskHandleMap.get(this.getProcessDefineKey());
        }

        return null;
    }

    /**
     * 获取流程操作用户信息，同时检查如果获取失败抛异常
     */
    public PlatformUserDto getFlowOperatorUser(@NotNull String operatorAccount) {

        //操作用户

        PlatformUserDto operatorUser = userService.findByUsername(operatorAccount);
        if (Objects.isNull(operatorUser)) {
            throw PlatformException.error("未找到流程发起人信息");
        }
        return operatorUser;
    }

    /**
     * 创建流程
     */
    private void checkDataBeforeCreateFlow(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount){
        //流程表单必填等校验
        Assert.notNull(flowDataDto.getFormMainData(), "创建流程表单信息不能为空");
        flowDataDto.setProcessDefineKey(this.getProcessDefineKey());

        //为防止注入，先清空
        flowDataDto.setTaskAssignee(new HashMap<>());
        flowDataDto.setConditionalVariable(new HashMap<>());

        //填充流程发起人信息
        PlatformUserDto operatorUser = this.getFlowOperatorUser(operatorAccount);
        flowDataDto.getFormMainData().setCreateOperator(operatorUser.getUsername());
        flowDataDto.getFormMainData().setCreateOperatorName(operatorUser.getName());

        //其它发起流程创建的补充检查
    }

    /**
     * 创建流程
     */
    public ParamDoTaskRespDto createFlow(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {

        //保存草稿时不需要检查
        if (FlowDataDto.BEGIN_TASK.equals(flowDataDto.getCreateToTaskDefinitionKey())) {
            log.info("创建流程至草稿状态");
        }

        //【前置检查】必要的检查以及常量初始化
        this.checkDataBeforeCreateFlow(flowDataDto,operatorAccount);

        //【任务处理前的处理】，比较常见的是个性化的TaskAssignee/ConditionalVariable设置
        this.getFlowTaskHandle().handleProcessBeforeCreate(flowDataDto);

        //操作用户
        PlatformUserDto operatorUser = this.getFlowOperatorUser(operatorAccount);


        TransactionStatus status = null;
        ParamDoTaskRespDto createFlowResponse = new ParamDoTaskRespDto();
        TYPEFORM flowableForm = flowDataDto.getFormMainData();
        try {
            // 事务定义x
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            // 每次都开启一个新事务
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 获取事务状态
            status = transactionManager.getTransaction(def);
            //2.表单内容（发起流程，表单内容为辅助）
            FlowStartupFormDto formDto = new FlowStartupFormDto();
            formDto.setTitle(flowableForm.getProcessTitle());
            //formDto.setComment("xx");//发起备注
            formDto.setCreatorId(operatorUser.getUsername());
            formDto.setCreatorName(operatorUser.getName());

            ParamCreateDto paramCreateDto = new ParamCreateDto();
            paramCreateDto.setSysid(PlatformConstant.SYS_ID_GATEWAY);
            paramCreateDto.setProcessDefinitionKey(this.getProcessDefineKey());
            //【重要！】这字段标识发起人！！！
            paramCreateDto.setUserid(operatorAccount);
            //纯粹为了flowable创建content需要一个JSON表单数据
            paramCreateDto.setContent(JSONObject.toJSON(formDto).toString());
            //各节点处理人
            paramCreateDto.setTaskAssignee(flowDataDto.getTaskAssignee());
            //控制流程节点变量
            paramCreateDto.setConditionalVariable(flowDataDto.getConditionalVariable());
            //评论附言
            if (Objects.nonNull(flowDataDto.getCommentDto())) {
                paramCreateDto.setCreateComment(flowDataDto.getCommentDto().getFullMessage());
            }
            //未启流程保存草稿时，CreateToTaskDefinitionKey变量为"beginTask"，流程引擎会在创建后调到初始节点
            if (StrUtil.isNotBlank(flowDataDto.getCreateToTaskDefinitionKey())) {//创建至草稿状态
                paramCreateDto.setCreateToTaskDefinitionKey(flowDataDto.getCreateToTaskDefinitionKey());
            }

            //4.微服务创建flowable流程
            FlowableResponse<ResponseCreateDto> createFlowableFlowResponse = flowableService.create(paramCreateDto);
            if (createFlowableFlowResponse.getStatus() == 0) {
                createFlowResponse.setProcessId(createFlowableFlowResponse.getData().getProcessId());
                flowDataDto.setProcessId(createFlowableFlowResponse.getData().getProcessId());
                log.info("流程关联，{}", createFlowResponse);
            } else {
                throw PlatformException.error(String.format("流程创建失败，{%s}，错误码={%s}-，原因：{%s}",
                        flowableForm.getProcessTitle(), createFlowableFlowResponse.getStatus(), createFlowableFlowResponse.getMsg()));
            }

            //流程表单数据保存【重要】自定义流程需要扩展保存
            ParamDoTaskRespDto saveRespDto = this.saveOrUpdateForm(flowDataDto, operatorAccount);

            //创建流程后置处理
            this.processCreateAfterHandle(flowDataDto, operatorAccount);

            //提交事务
            transactionManager.commit(status);


            //流程发起后续事件处理，MQ异步处理
            ResponseSituationDto afterAuditFlowInfo = flowableService.getProcessInfo(createFlowResponse.getProcessId());
            WorkflowMsgDto msgDto = new WorkflowMsgDto();
            msgDto.setPubProdFlow(true);
            msgDto.setMsgId(String.valueOf(System.currentTimeMillis()));
            msgDto.setProcessId(createFlowResponse.getProcessId());
            msgDto.setProcessDefineKey(this.getProcessDefineKey());
            msgDto.setMsgType(FlowConstant.FLOW_TASK_CREATE);
            msgDto.setAfterAuditFlowTaskList(afterAuditFlowInfo.getCurrentTaskInfoDtoList());
            msgDto.setOperatorAccount(operatorAccount);
            if (StrUtil.isNotEmpty(flowDataDto.getCreateToTaskDefinitionKey())) {
                msgDto.setCreateToBeginTask(true);
            }
            easyFlowMessageSender.sendMessage(msgDto);


            return createFlowResponse;
        } catch (Exception e) {
            log.error(e.getMessage());
            //flowable回滚
            if (Objects.nonNull(createFlowResponse) && Objects.nonNull(createFlowResponse.getProcessId())) {
                log.error("流程删除:" + createFlowResponse.getProcessId());
                flowableService.deleteProcess(ParamDeleteDto.builder().processIdList(Collections.singletonList(createFlowResponse.getProcessId())).build());
            }
            if (Objects.nonNull(status)) {
                transactionManager.rollback(status);
            }
            throw e;
        }
    }

    /**
     * @param operatorAccount 处理人
     */
    public ParamDoTaskRespDto taskAuditPass(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {

        //TODO 根据taskId初始化数据
        //        FlowDoTaskRespDto respDto = flowableService.validCheckTaskBeforeSaveFormOrAuditTask(param.getTaskId());

        //【1.任务合法性数据】
        FlowDoTaskRespDto respDto = flowableService.validCheckTaskBeforeSaveFormOrAuditTask(flowDataDto.getTaskId());
        SpringUtil.copyPropertiesIgnoreNull(respDto, flowDataDto);

        //【2.公共处理】检查文件必传性， TODO
        // =》注意，表单还未保存，因此需要取提交的taskDto.getFlowableFormData().getNeedCustodySeal()字段信息
//        this.checkNeedFileUploadedOfTask(taskDto.getDocList(), isSetProd, taskDto.getTaskId()
//                , taskDto.getTaskDefinitionKey(), taskDto.getProcessId()
//                , taskDto.getFlowableFormData().getNeedCustodySeal());

        //【3.获取任务审核前的流程信息】
        ResponseSituationDto beforeAuditFlowInfo = flowableService.getProcessInfo(flowDataDto.getProcessId());
        flowDataDto.setBeforeAuditFlowInfo(beforeAuditFlowInfo);
        //END OF【公共处理】查询任务基础信息

        flowDataDto.setProcessDefineKey(this.getProcessDefineKey());

        //为防止注入，先清空
        flowDataDto.setTaskAssignee(new HashMap<>());
        flowDataDto.setConditionalVariable(new HashMap<>());
        //【任务处理前的处理】，比较常见的是个性化的TaskAssignee/ConditionalVariable设置
        this.getFlowTaskHandle().handleTaskPassBefore(flowDataDto);




        //审核事务通过
        TransactionStatus status = null;
        FlowableResponse<ResponseMsgDto> flowableResponse;
        try {

            // 事务定义
            DefaultTransactionDefinition def = new DefaultTransactionDefinition();
            // 每次都开启一个新事务
            def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
            // 获取事务状态
            status = transactionManager.getTransaction(def);


            //流程表单数据保存【重要】自定义流程需要扩展保存
            ParamDoTaskRespDto saveRespDto = this.saveOrUpdateForm(flowDataDto, operatorAccount);

            //审核流程通过，组织表单内容、审核注入变量、评论等
            ParamDoTaskDto paramDotaskDto = new ParamDoTaskDto();
            paramDotaskDto.setSysid(PlatformConstant.SYS_ID_GATEWAY);
            paramDotaskDto.setTaskId(flowDataDto.getTaskId());
            paramDotaskDto.setComment(flowableService.initCommentDto(flowDataDto.getCommentDto()));
            paramDotaskDto.setTitle(flowDataDto.getProcessTitle());//TODO 审核时的processTitle网关应该去除
            paramDotaskDto.setContent(JsonTool.objectToJson(paramDotaskDto));//flowable网关保存每次审批的全量数据
            //重置审批人
            paramDotaskDto.setTaskAssignee(flowDataDto.getTaskAssignee());
            //重置变量
            paramDotaskDto.setConditionalVariable(flowDataDto.getConditionalVariable());

            //TODO: 用TCC完成事务
            //调用网关审核，注意前面表单的保存与这里审批通过，事物可能不一致，暂时不予处理这种不一致的情况
            flowableResponse = flowableService.taskAuditPass(paramDotaskDto);
            if (0 == flowableResponse.getStatus()) {

                //提交事务
                transactionManager.commit(status);

                //流程审核通过后续事件处理，MQ异步处理
                WorkflowMsgDto msgDto = new WorkflowMsgDto();
                ResponseSituationDto afterAuditFlowInfo = flowableService.getProcessInfo(flowDataDto.getProcessId());
                msgDto.setMsgId(String.valueOf(System.currentTimeMillis()));
                msgDto.setPubProdFlow(true);
                msgDto.setProcessId(flowDataDto.getProcessId());
                msgDto.setOperatorAccount(operatorAccount);
                msgDto.setProcessDefineKey(this.getProcessDefineKey());
                msgDto.setMsgType(FlowConstant.FLOW_TASK_PASS);
                msgDto.setTaskDefinitionKey(flowDataDto.getTaskDefinitionKey());
                msgDto.setCurrentTaskName(flowDataDto.getCurrentTaskInfo().getCurrentTaskName());
                msgDto.setBeforeAuditFlowTaskList(flowDataDto.getBeforeAuditFlowInfo().getCurrentTaskInfoDtoList());
                msgDto.setAfterAuditFlowTaskList(afterAuditFlowInfo.getCurrentTaskInfoDtoList());
                easyFlowMessageSender.sendMessage(msgDto);

                ParamDoTaskRespDto doTaskRespDto = new ParamDoTaskRespDto();
                doTaskRespDto.setProcessId(flowDataDto.getProcessId());
                doTaskRespDto.setComment(doTaskRespDto.getComment());
                return doTaskRespDto;
            } else {
                throw PlatformException.error(String.format("流程审核失败，错误码%s，原因：%s，详情：%s",
                        flowableResponse.getStatus(), flowableResponse.getMsg(), flowableResponse.getData()));
            }
        } catch (Exception e) {
            log.error(e.getMessage() + ", status:" + status);
            if (status != null) {
                transactionManager.rollback(status);
            }
            throw e;
        }
    }


    /**
     * @param flowDataDto     流程id或任务id，仅用到这两个字段
     * @param operatorAccount 处理人
     */
    public FlowDataDto<TYPEFORM> findByProcessIdOrTaskId(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        String taskId = flowDataDto.getTaskId(), processId = flowDataDto.getProcessId();


        if (StrUtil.isEmpty(taskId) && StrUtil.isEmpty(processId)) {
            throw PlatformException.error("查询流程时，需要提供流程实例Id或者任务Id和流程节点标识");
        }


        ResponseSituationDto currentTaskInfo = null;
        ProcessEditConfigDto editConfigDto = new ProcessEditConfigDto();
        String HandleProcessMode = DictConstant.FLOWABLE_HANDLE_MODE_VIEW;
        //流程结束或者抄送查看流程时，仅根据processId检索要素信息
        if (StrUtil.isEmpty(taskId)) {
            currentTaskInfo = flowableService.getProcessInfo(processId);
            flowDataDto.setBeforeAuditFlowInfo(currentTaskInfo);
            flowDataDto.setCurrentTaskInfo(new ResponseSituationDto());//减轻前段判空处理
        } else {

            FlowableResponse<ResponseSituationDto> flowableTaskInfoResponse = flowableService.getTaskInfo(taskId);
            if (flowableTaskInfoResponse.getStatus() != 0 || StrUtil.isEmpty(flowableTaskInfoResponse.getData().getCurrentTaskId())) {
                throw PlatformException.error(String.format("流程引擎未查询到任务信息: %s", taskId));
            } else {
                currentTaskInfo = flowableTaskInfoResponse.getData();
                editConfigDto = processEditConfigService.getProcessEditConfigDto(currentTaskInfo.getProcessDefineKey(), currentTaskInfo.getCurrentTaskDefinitionKey());
                HandleProcessMode = DictConstant.FLOWABLE_HANDLE_MODE_EDIT;
                flowDataDto.setTaskId(currentTaskInfo.getCurrentTaskId());
                flowDataDto.setTaskDefinitionKey(currentTaskInfo.getCurrentTaskDefinitionKey());
                flowDataDto.setCurrentTaskInfo(currentTaskInfo);

                //流程任务信息
                ResponseSituationDto flowableInfoResponse = flowableService.getProcessInfo(currentTaskInfo.getProcessId());
                flowDataDto.setBeforeAuditFlowInfo(flowableInfoResponse);
            }
        }

        flowDataDto.setProcessEditConfigDto(editConfigDto);
        //task 任务详情
        flowDataDto.setProcessId(currentTaskInfo.getProcessId());
        flowDataDto.setProcessDefineKey(currentTaskInfo.getProcessDefineKey());
        flowDataDto.setProcessTitle(currentTaskInfo.getProcessTitle());
        flowDataDto.setHandleProcessMode(HandleProcessMode);


        //【查询具体每个流程的个性化表单数据】
        flowDataDto = this.findFormDataByProcessId(flowDataDto, operatorAccount);

        return flowDataDto;
    }


    /**
     * 后处理处理消息
     */
    public void processMsg(WorkflowMsgDto msgDto) {
        FlowDataDto queryFlowDataDto = new FlowDataDto();
        queryFlowDataDto.setProcessId(msgDto.getProcessId());
        queryFlowDataDto.setProcessDefineKey(msgDto.getProcessDefineKey());
        queryFlowDataDto.setTaskId(msgDto.getTaskId());

        queryFlowDataDto = this.findByProcessIdOrTaskId(queryFlowDataDto, msgDto.getOperatorAccount());
        msgDto.setAfterFlowDataDto(queryFlowDataDto);

        String msgType = msgDto.getMsgType();

        if (FlowConstant.FLOW_TASK_CREATE.equals(msgType)) {//任务创建后的后处理
            this.getFlowTaskHandle().handleTaskCreate(msgDto);
        } else if (FlowConstant.FLOW_TASK_PASS.equals(msgType)) {
            this.getFlowTaskHandle().handleTaskPassAfter(msgDto);//审核通过的后处理
        } else if (FlowConstant.FLOW_TASK_REJECT.equals(msgType)) {//审核拒绝的后处理
            this.getFlowTaskHandle().handleTaskRejectAfter(msgDto);
        } else if (FlowConstant.FLOW_TASK_VIEW.equals(msgType)) {//查看
            this.getFlowTaskHandle().handleProcessViewAfter(msgDto);
        } else {
            log.error("没有流程异步任务的类型，msgType=" + msgType);
        }
    }


    /**
     * 退回
     */
    public ParamDoTaskRespDto reject(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotNull String operatorAccount) {
        //任务合法性数据 TODO
//        flowableService.validCheckTaskBeforeSaveFormOrAuditTask(param.getTaskId());

        flowDataDto = this.findByProcessIdOrTaskId(flowDataDto, operatorAccount);

        // 【任务退回前的处理】
        this.getFlowTaskHandle().handleTaskRejectBefore(flowDataDto);

        ParamRollbackDto rollbackDto = new ParamRollbackDto();

        PlatformUserDto operatorUser = this.getFlowOperatorUser(operatorAccount);

        //流程注入变量更新，TODO 删除，目前退回一般不需要初始化group和变量

        //任务ID
        rollbackDto.setTaskId(flowDataDto.getTaskId());
        rollbackDto.setSysid(PlatformConstant.SYS_ID_GATEWAY);
        rollbackDto.setComment(flowableService.initCommentDto(flowDataDto.getCommentDto()).getFullMessage());
        rollbackDto.setTargetTask(flowDataDto.getRollbackToTaskDefineKey());
        rollbackDto.setContent(JsonTool.objectToJson(rollbackDto));
//        rollbackDto.setTaskAssignee(taskAssignee);
//        rollbackDto.setConditionalVariable(conditionalVariable);

        FlowableResponse flowableResponse = null;
        if (StrUtil.isEmpty(flowDataDto.getRollbackToTaskDefineKey())) {//退回至上一步
            flowableResponse = flowableService.taskAuditReject(rollbackDto);
        } else {//退回至指定节点，TODO 退回至指定节点需要进一步测试
            flowableResponse = flowableService.backToSelect(rollbackDto);
        }

        if (0 != flowableResponse.getStatus()) {
            throw PlatformException.error("流程退回失败:" + flowableResponse.getMsg());
        } else {

            //流程退回后续事件处理，MQ异步处理
            WorkflowMsgDto msgDto = new WorkflowMsgDto();
            ResponseSituationDto afterAuditFlowInfo = flowableService.getProcessInfo(flowDataDto.getProcessId());
            msgDto.setPubProdFlow(true);
            msgDto.setMsgId(String.valueOf(System.currentTimeMillis()));
            msgDto.setProcessId(flowDataDto.getProcessId());
            msgDto.setOperatorAccount(operatorAccount);
            msgDto.setProcessDefineKey(this.getProcessDefineKey());
            msgDto.setMsgType(FlowConstant.FLOW_TASK_REJECT);
            msgDto.setPassProperly(false);
            msgDto.setTaskDefinitionKey(flowDataDto.getTaskDefinitionKey());
            msgDto.setCurrentTaskName(flowDataDto.getCurrentTaskInfo().getCurrentTaskName());
            msgDto.setBeforeAuditFlowTaskList(flowDataDto.getBeforeAuditFlowInfo().getCurrentTaskInfoDtoList());
            msgDto.setAfterAuditFlowTaskList(afterAuditFlowInfo.getCurrentTaskInfoDtoList());
            easyFlowMessageSender.sendMessage(msgDto);


            ParamDoTaskRespDto rejectRespDto = new ParamDoTaskRespDto();
            rejectRespDto.setProcessId(flowDataDto.getTaskId());
            rejectRespDto.setComment(rejectRespDto.getComment());
            return rejectRespDto;
        }
    }

    /**
     * 保存流程表单通用处理，真实数据库保存处理通过saveOrUpdateFormData()完成
     */
    public ParamDoTaskRespDto saveOrUpdateForm(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotBlank String operatorAccount){
        TYPEFORM formMainData = flowDataDto.getFormMainData();

        if (Objects.isNull(formMainData)) {
            throw PlatformException.error("保存流程表单数据为空");
        }

        //初始化流程的公共字段
        List<String> filedNameList=Arrays.asList("processId","processDefineKey");
        for (String fieldName : filedNameList) {
            if (ReflectUtil.hasField(formMainData.getClass(), fieldName)) {
                ReflectUtil.setFieldValue(formMainData, fieldName, flowDataDto.getProcessId());
            }
        }

        //调用实际的保存表单方法
        return this.saveOrUpdateFormData(flowDataDto,operatorAccount);
    }

    /**
     * 保存流程表单每个流程类型需要各自定义
     */
    public abstract ParamDoTaskRespDto saveOrUpdateFormData(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotBlank String operatorAccount);


    /**
     * 通过processId获取流程表单信息
     */
    public abstract FlowDataDto<TYPEFORM> findFormDataByProcessId(@NotNull FlowDataDto<TYPEFORM> flowDataDto, @NotBlank String operatorAccount);

    /**
     * 节点审批后置处理(默认不需要)
     */
    protected abstract void processCreateAfterHandle(FlowDataDto<TYPEFORM> flowDataDto, @NotBlank String operatorAccount);
}
